package io.gitee.gemini.utis;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 处理反射的工具类
 */
public class ReflectUtil {


    private ReflectUtil() {
    }

    //字段缓存
    public static Cache<Class<?>, Field[]> FIELDS_CACHE = Caffeine.newBuilder().expireAfterAccess(3, TimeUnit.MINUTES).maximumSize(10).build();


    /**
     * 反射获取对象的所有字段
     *
     * @param clazz 目标class
     * @return 字段集合（去重）
     */
    public static Field[] getClassFields(Class<?> clazz) {
        //从缓存读取属性 （不存在时查询并添加到本地缓存）
        Field[] result = FIELDS_CACHE.get(clazz, ReflectUtil::getFields);

        return result;
    }


    private static Field[] getFields(Class<?> clazz) {

        Field[] fields = clazz.getDeclaredFields();
        List<Field> result = new ArrayList<>();
        for (Field field : fields) {
            if (Modifier.isStatic(field.getModifiers())) {
                continue;
            }
            result.add(field);
        }

        //遍历获取父类
        Class<?> superclass = clazz.getSuperclass();
        while (superclass != null && superclass != Object.class) {
            Field[] declaredFields = superclass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                if (Modifier.isStatic(declaredField.getModifiers())) {
                    continue;
                }
                result.add(declaredField);
            }
            superclass = superclass.getSuperclass();
        }
        Field[] r = result.toArray(new Field[]{});
        return r;
    }


}
